package com.chenjinyan.back.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.chenjinyan.back.dao.ConnectionRepository;
import com.chenjinyan.back.entity.ConnectionEntity;
import com.chenjinyan.back.entity.UserEntity;
import com.chenjinyan.back.service.ConnectionService;
import com.chenjinyan.back.utils.ResultUtil;
import com.chenjinyan.back.utils.StringUtils;
import com.chenjinyan.back.vo.ConnectionVo;
import com.chenjinyan.back.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class ConnectionServiceImpl implements ConnectionService {
    @Autowired
    ConnectionRepository connectionRepository;
    @PersistenceContext
    private EntityManager em;

    @Override
    public Result insertConnection(ConnectionVo connectionVo) throws ParseException {
        Result result = ResultUtil.success();
        String name = connectionVo.getName();
        String url = connectionVo.getUrl();
        String description = connectionVo.getDescription();
        int i = connectionRepository.insertConnection(name, url, description);
        if (i > 0) {
            result.setMsg("新增成功");
        }
        return result;
    }

    @Override
    public Result getConnection(ConnectionVo connectionVo) throws ParseException {
        Result result = ResultUtil.success();
        String name = connectionVo.getName();
        String url = connectionVo.getUrl();
        String description = connectionVo.getDescription();
        String pageNo = connectionVo.getPageNo();
        String pageSize = connectionVo.getPageSize();
        Map<String, String> map = new HashMap<>(16);
        if (null == pageNo || "".equals(pageNo)) {
            pageNo = "1";
        }
        if (null == pageSize || "".equals(pageSize)) {
            pageSize = "20";
        }
        StringBuilder sql = builderSql();
        StringBuilder sqlCount = builderSqlCount();

        if (null != name && !"".equals(name)) {
            sql.append(" AND NAME like CONCAT('%',:name,'%')");
            sqlCount.append(" AND NAME like CONCAT('%',:name,'%')");
        }
        if (null != url && !"".equals(url)) {
            sql.append(" AND URL like CONCAT('%',:url,'%')");
            sqlCount.append(" AND URL like CONCAT('%',:url,'%')");
        }
        if (null != description && !"".equals(description)) {
            sql.append(" AND DESCRIPTION like CONCAT('%',:description,'%')");
            sqlCount.append(" AND DESCRIPTION like CONCAT('%',:description,'%')");
        }

        Query q = em.createNativeQuery(sql.toString(), ConnectionEntity.class);
        Query countQ = em.createNativeQuery(sqlCount.toString(), ConnectionEntity.class);

        if (!StringUtils.isEmpty(name) && !StringUtils.isEmpty(name)) {
            q.setParameter("name", name);
            countQ.setParameter("name", name);
        }
        if (!StringUtils.isEmpty(url) && !StringUtils.isEmpty(url)) {
            q.setParameter("url", url);
            countQ.setParameter("url", url);
        }
        if (!StringUtils.isEmpty(description) && !StringUtils.isEmpty(description)) {
            q.setParameter("description", description);
            countQ.setParameter("description", description);
        }
        q.setFirstResult((Integer.parseInt(pageNo) - 1) * Integer.parseInt(pageSize));
        q.setMaxResults(Integer.parseInt(pageSize));
        List<ConnectionEntity> list = q.getResultList();

        Integer recordCount = countQ.getResultList().size();
        Long pageCount = getPageCount(Integer.parseInt(pageSize), recordCount.longValue());

        map.put("currentPage", pageNo);
        map.put("pageSize", pageSize);
        map.put("recordCount", String.valueOf(recordCount));
        if(pageCount==0){
            pageCount++;
        }
        map.put("pageCount", String.valueOf(pageCount));
        map.put("data", JSONObject.toJSONString(list, SerializerFeature.WriteMapNullValue));
        result.setData(map);
        return result;
    }

    @Override
    public List<ConnectionEntity> getConnectionById(ConnectionVo connectionVo) throws ParseException {
        Long id = connectionVo.getId();
        StringBuilder sql = builderSql();
        sql.append(" AND ID=:id ");
        Query q = em.createNativeQuery(sql.toString(), ConnectionEntity.class);
        q.setParameter("id", id);
        return q.getResultList();
    }

    @Override
    public Result delConnection(List<String> ids) throws ParseException {
        Result result = ResultUtil.success();
        StringBuilder getSql = builderGetSql();
        Query query = em.createNativeQuery(getSql.toString(), ConnectionEntity.class);
        query.setParameter("ids", ids);

        List<UserEntity> list = query.getResultList();
        if (null != list && list.size() == ids.size()) {
            StringBuilder sql = builderDelSql();
            Query q = em.createNativeQuery(sql.toString());
            q.setParameter("ids", ids);
            q.executeUpdate();
            result.setMsg("删除成功");
        } else {
            result.setCode("000001");
            result.setMsg("fail");
            result.setMsg("删除失败，请检查传入id");
        }
        return result;
    }

    @Override
    public Long updateConnection(ConnectionVo connectionVo) throws ParseException {
        Result result = ResultUtil.success();
        ConnectionEntity connectionEntity = new ConnectionEntity();
        connectionEntity.setId(connectionVo.getId());
        connectionEntity.setName(connectionVo.getName());
        connectionEntity.setDescription(connectionVo.getDescription());
        connectionEntity.setUrl(connectionVo.getUrl());
        ConnectionEntity connectionEntityNew = connectionRepository.saveAndFlush(connectionEntity);
        return connectionEntityNew.getId();
    }

    private StringBuilder builderSql() {
        StringBuilder sql = new StringBuilder(500);
        sql.append("SELECT ")
                .append("ID,NAME,URL,DESCRIPTION ")
                .append("FROM lost_and_find_connection ")
                .append("WHERE 1=1 ");
        return sql;
    }

    private StringBuilder builderSqlCount() {
        StringBuilder sql = new StringBuilder(500);
        sql.append("SELECT ")
                .append("ID,NAME,URL,DESCRIPTION ")
                .append("FROM lost_and_find_connection ")
                .append("WHERE 1=1 ");
        return sql;
    }

    private StringBuilder builderDelSql() {
        StringBuilder sql = new StringBuilder(500);
        sql.append("DELETE ")
                .append("FROM lost_and_find_connection ")
                .append("WHERE ID IN :ids ");
        return sql;
    }

    private StringBuilder builderGetSql() {
        StringBuilder sql = new StringBuilder(500);
        sql.append("SELECT * FROM ")
                .append("lost_and_find_connection ")
                .append("WHERE ID IN :ids");
        return sql;
    }

    private StringBuilder builderUpdateSql() {
        StringBuilder sql = new StringBuilder(500);
        sql.append("UPDATE lost_and_find_connection SET ")
                .append("NAME=:name, ")
                .append("URL=:url, ")
                .append("DESCRIPTION=:description ")
                .append("WHERE ID=:id");
        return sql;
    }

    private Long getPageCount(Integer pageSize, Long recordCount) {
        return recordCount % pageSize == 0 ? recordCount / pageSize : recordCount / pageSize + 1;
    }
}
